#include "prompt.h"
#include <unistd.h>
#include <sys/types.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/select.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

/**
 * 在命令行显示提示信息，我想用异步的方式显示，
 * 所以用了全局的管道变量pipe_prompt
 * 
 */

static int s_pipe_prompt[2];

struct stySystemUser{
    u_int8_t    m_PC_PEN;   //0表示PC,1表示笔
    int64_t     m_timestamp;//时间戳
    char        name[128];  //姓名
    u_int8_t    m_is_study;   //是否在学习
    struct bufferevent *bev;//
};
static struct Prompt_data
{
    int16_t     port;
    u_int32_t   m_online_pen_num;
    u_int32_t   m_online_user_num;
    u_int32_t   m_online_tatal_num; //总的在线人数
    struct stySystemUser *m_user;
}s_prompt_data;


void *prompt_init(void *arg)
{
    fd_set rfds;
    s_prompt_data.port = *(short *)arg;
    
    /* 1.创建管道 */
    int err = pipe(s_pipe_prompt);
    assert(err == 0);

    /* 2.显示信息 */
    show_prompt_data();

    /* 3.循环监听 */
    while(1){
        FD_ZERO(&rfds);
        FD_SET(s_pipe_prompt[0],&rfds);
        err = select(s_pipe_prompt[0]+1,&rfds,NULL,NULL,NULL);
        assert(err != -1);

        if(FD_ISSET(s_pipe_prompt[0],&rfds)){
            readFromPipe();
        }else{
            perror("select");
            break;
        }
    }
    close(s_pipe_prompt[0]);
    close(s_pipe_prompt[1]);
    return arg;
}
void show_prompt_data()
{
    system("clear");
    printf("** Design of Learning System Based on Internet of Things **\n");
    printf("*  listen port:%d\n",s_prompt_data.port);
    printf("*  online pen  number : %d\n",s_prompt_data.m_online_pen_num);
    printf("*  online user number : %d\n",s_prompt_data.m_online_user_num);
    printf("* _____________\n");
}
/**
 * @brief  读取管道中的数据
 * @note   
 * @retval None
 */
void readFromPipe()
{
    u_int32_t displayEvent;
    ssize_t nbytes = read(s_pipe_prompt[0],&displayEvent,sizeof(displayEvent));
    if(nbytes != sizeof(displayEvent)){

        return ;
    }
}
int set_study_status(u_int32_t pos,u_int8_t is_study)
{
    if(pos >= s_prompt_data.m_online_tatal_num || pos <0)
        return -1;
    struct stySystemUser *user = s_prompt_data.m_user;
    (user+pos)->m_is_study = is_study;
    return 0;
}
u_int8_t is_study(u_int32_t pos)
{
    if(pos >= s_prompt_data.m_online_tatal_num || pos <0)
        return 0;
    struct stySystemUser *user = s_prompt_data.m_user;
    return (user+pos)->m_is_study;
}
u_int32_t find_pos_byBev(struct bufferevent *bev)
{
    int i = s_prompt_data.m_online_tatal_num;
    struct stySystemUser *user = s_prompt_data.m_user;
    while(i>=0){
        if((user+i)->bev == bev)
            break;
        i--;
    }
    return i;
}
char *find_name_byBev(struct bufferevent *bev)
{
    int i = s_prompt_data.m_online_tatal_num-1;
    struct stySystemUser *user = s_prompt_data.m_user;
    while(i>=0){
        if((user+i)->bev == bev)
            return (user+i)->name;
        i--;
    }
    return NULL;
}
u_int32_t find_pen_pos_byName(char *name)
{
    int i = s_prompt_data.m_online_tatal_num-1;
    struct stySystemUser *user = s_prompt_data.m_user;
    while(i>=0){
        if(memcmp((user+i)->name,name,strlen(name))==0 && (user+i)->m_PC_PEN==E_PEN)
            break;
        i--;
    }
    return i;
}
/**
 * @brief  
 * @note   
 * @param  *bev: 
 * @param  *name: 
 * @param  PC_PEN_flag: 
 * @retval 
 */
u_int32_t add_user(struct bufferevent *bev,char *name,int PC_PEN_flag)
{
    /* 1.更新全局变量 */
    s_prompt_data.m_online_pen_num += (PC_PEN_flag == E_PEN);
    s_prompt_data.m_online_user_num += (PC_PEN_flag == E_PC);

    /* 2.查找是否有已经删除的用户字段空出来 */
    struct stySystemUser *user = s_prompt_data.m_user;
    int i=0;
    for(;i<s_prompt_data.m_online_tatal_num;i++){
        if(user[i].bev == NULL && user[i].name[0]==0){
            user+=i;
            break;
        }
    }
    if(i >= s_prompt_data.m_online_tatal_num){
        s_prompt_data.m_online_tatal_num ++;
        s_prompt_data.m_user = realloc(s_prompt_data.m_user,
                sizeof(struct stySystemUser)*s_prompt_data.m_online_tatal_num);
        assert(s_prompt_data.m_user != NULL);
        user = s_prompt_data.m_user+s_prompt_data.m_online_tatal_num-1;
    }

    /* 3.填写新的用户字段 */
    user->bev=bev;
    user->m_PC_PEN = PC_PEN_flag;
    memcpy(user->name,name,strlen(name)+1);
    user->m_timestamp = time(NULL);

    /* 4.通知显示线程 */
    show_prompt_data();

    return s_prompt_data.m_online_tatal_num -1;
}
/**
 * @brief  这里有bug，不能这样写
 * @note   
 * @param  *bev: 
 * @retval None
 */
void del_user(struct bufferevent *bev)
{
    if(s_prompt_data.m_online_tatal_num <= 0){
        return ;
    }
    struct stySystemUser *user = s_prompt_data.m_user;
    int i=0;
    for(;i<s_prompt_data.m_online_tatal_num;i++){
        if(user[i].bev == bev){
            printf("find the user and ready to delete\n");
            s_prompt_data.m_online_pen_num -=(E_PEN == user[i].m_PC_PEN);
            s_prompt_data.m_online_user_num -=(E_PC == user[i].m_PC_PEN);
            //memcpy(&user[i],&user[--s_prompt_data.m_online_tatal_num],sizeof(struct stySystemUser));
            user[i].bev=NULL;
            user[i].m_timestamp=0;
            user[i].name[0]='\0';
            break;
        }
    }
    if(i>=s_prompt_data.m_online_tatal_num)
        printf("not find this user\n");
    bufferevent_free(bev);
    show_prompt_data();
}
int64_t gettimestamp(u_int32_t position)
{
    if(position >= s_prompt_data.m_online_tatal_num || position <0)
        return 0;
    struct stySystemUser*user = s_prompt_data.m_user+position;
    return user->m_timestamp;
}
int64_t get_pen_timestamp(u_int32_t pos)
{
    int64_t timestamp;
    if(pos >= s_prompt_data.m_online_tatal_num || pos <0){
        return -1;
    }else{
        struct stySystemUser *user = s_prompt_data.m_user+pos;
        timestamp = user->m_timestamp;
        timestamp *= is_study(pos);
    }
    return timestamp;
}
void update_timestamp(u_int32_t position)
{
    if(position >= s_prompt_data.m_online_tatal_num)
        return ;
    struct stySystemUser*user = s_prompt_data.m_user+position;
    user->m_timestamp = time(NULL);
}


